// 公共基类双击事件

import Konva from "konva";
import { Draw } from "../../../Draw/Draw";
import { IKonva } from "../../../Interface/IKonva";
import { setGroupDraggable } from "./group-draggable";
import { replaceInnerHtml } from "../../../Utils/konva";

/**
 * Konva Graph 基类双击事件处理函数
 */
export function groupDbclick(e: IKonva.Event, draw: Draw) {
  e.cancelBubble = true;
  if (e.evt.button === 2) return;

  // 如果处于插入状态
  const stage = draw.getStage();
  if (stage.getAttr("insertShape")) return;

  // 取消形变 - 取消选中属性
  draw.clearTransformer();
  draw.clearLineControl();
  draw.clearSelected();

  // 设置不可拖拽，防止输入抖动
  setGroupDraggable(draw, false);

  const group = e.target.parent!;

  // 如果是动画Label双击 则直接返回
  if (group.name() === "konva-animation-label") return;

  // 找到节点下的唯一文本节点
  const textNode = <Konva.Text>group.findOne("Text")!;

  if (!textNode) return setGroupDraggable(draw, true);

  // 获取 contenteditable
  const root = draw.getRootBox();
  const selector = ".konva-root-container-textarea";
  const textareaBox = <HTMLDivElement>root.querySelector(selector);
  const textarea = textareaBox.querySelector("div")!;

  // 保存旧文字，后清空文本
  const { text: oldText, fontSize, fill, rotation } = textNode.attrs;
  textNode.setAttrs({ text: "" });

  // 还需要处理定位问题，将 textarea 定位止当前容器内，且需要设置宽高
  const { x, y, width, height, realWidth, realHeight } = group!.attrs;

  if (textNode.getAttr("onlyText")) textareaBox.style.display = "block";
  else textareaBox.style.display = "flex";

  textareaBox.style.transform = `rotate(${rotation || 0}deg)`;
  textareaBox.style.left = x + "px";
  textareaBox.style.top = y + "px";
  textareaBox.style.width = (realWidth || width) + "px";
  textareaBox.style.height = (realHeight || height) + "px";
  textarea.style.fontSize = fontSize + "px";
  textarea.innerText = oldText || ""; //  获取当前 text 文本
  textarea.style.color = fill;

  // 将光标移动止末尾
  const range = document.createRange();
  range.selectNodeContents(textarea);
  range.collapse(false);
  const sel = <Selection>window.getSelection();
  sel.removeAllRanges();
  sel.addRange(range);
  textarea.focus();

  // 监听失焦事件、enter 事件
  textarea.addEventListener("blur", blurHandle);
  textarea.addEventListener("keydown", enterHandle);
  textarea.addEventListener("input", inputHandle);

  // 执行文本框失焦事件
  function blurHandle() {
    textareaBox.style.display = "none";
    // 记得移除事件，不然会一直触发哈
    textarea.removeEventListener("blur", blurHandle);
    textarea.removeEventListener("keydown", enterHandle);
    // 恢复移动
    setGroupDraggable(draw, true);

    const text = textarea.innerHTML;

    if (oldText === text) return;
    const value = replaceInnerHtml(text);

    // 12<br>3 识别 br 进行 \n 替换
    textNode.setAttrs({ text: value });

    // 触发更新
    draw.render();

    // 广播协同
    draw.broadcast({
      type: `${group.id()}_textUpdate`,
      payload: {
        layerID: draw.getLayer()?.id(),
        text: value,
        groupID: group.id(),
      },
    });
  }

  // 回车事件
  function enterHandle(e: KeyboardEvent) {
    if (e.key === "Enter" && !e.shiftKey) blurHandle();
  }

  /**
   * 为了实现最佳的视觉效果，应该判断内部宽度是否超过外层容器，超过设置 100% 以达到换行输入
   */
  function inputHandle() {
    const text = textarea.innerText;
    const temp = document.createElement("span");
    // temp.style.font = font;
    temp.style.position = "absolute";
    temp.style.visibility = "hidden";
    temp.innerText = text;

    // 将元素添加到文档中
    document.body.appendChild(temp);

    // 获取宽度
    const width = temp.offsetWidth;

    // 移除临时元素
    document.body.removeChild(temp);

    const textareaBoxWidth = textareaBox.offsetWidth;
    if (width >= textareaBoxWidth) textarea.style.width = "100%";
    else textarea.style.width = "auto";
  }
}
